﻿using System;
using System.Collections;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.IO;
using System.Globalization;
using IL2LogParser;

namespace IL2LogParser
{
    class Program
    {
        /// <summary>
        /// Accepts an IL2 Mission File,Game log file and database connection information.
        /// The files are parsed and interesting information such as flight time, weapons, fuel, kills etc are recorded 
        /// and then written to the database.
        /// </summary>
        /// <param name="args"></param>
        static void Main(string[] args)
        {
            List<string> parseableActions = new List<string>();
            List<string> missionFile = new List<string>();
            List<string> missionPlayers = new List<string>();
            List<PlayerStats> playerStats = new List<PlayerStats>();
            string missionDate = "";
            string lastLine = "";
            parseableActions.Add("Mission:");
            parseableActions.Add("has connected");
            parseableActions.Add("has disconnected");
            parseableActions.Add("loaded weapons '");
            parseableActions.Add("in flight");
            parseableActions.Add("shot down by");
            parseableActions.Add("was killed");
            parseableActions.Add("damaged on the ground");
            parseableActions.Add("damaged by");
            parseableActions.Add("has chute destroyed by");
            parseableActions.Add("destroyed by");
            parseableActions.Add("landed at");
            parseableActions.Add("crashed at");
            parseableActions.Add("Mission BEGIN");
            parseableActions.Add("Mission END");
            //parseableActions.Add("damaged on the ground");

            parseableActions.Add("turned landing lights on");
            parseableActions.Add("turned landing lights off");
            parseableActions.Add("turned wingtip smokes on");
            parseableActions.Add("turned wingtip smokes off");
            parseableActions.Add("successfully bailed out");





            using (StreamReader reader = File.OpenText(args[0]))
            {
                while (!reader.EndOfStream)
                {
                    string line = reader.ReadLine();
                    missionFile.Add(line.Trim());
                }
            }

            MissionStats missionStats = new MissionStats();

            ExtractMissionAttributes(missionFile, missionStats);
            missionStats.MissionFile = args[0].ToString();
            missionStats.MissionName = args[0].Substring(args[0].LastIndexOf("\\") + 1, (args[0].IndexOf(".") - 1) - args[0].LastIndexOf("\\"));
            missionStats.MissionLogFile = args[1];

            #region ProcessMissionLog
            using (StreamReader reader = File.OpenText(args[1]))
            {
                int lineCounter = 0;
                while (!reader.EndOfStream)
                {
                    lineCounter++;
                    string line = reader.ReadLine().Trim();
                    lastLine = line;
                    if (NonAIActions(line))
                    {
                        // bool actionProcessed = false;
                        string currentAction = "";
                        foreach (string action in parseableActions)
                        {
                            if (line.Contains(action))
                            {

                                #region  Mission
                                if (action == "Mission:")
                                {
                                    if ("123456789".IndexOf(line.Substring(1, 1)) != -1)
                                    {
                                        missionDate = ParseSubString(line, "[", "]");

                                    }
                                    else
                                    {
                                        string extractDate = ParseSubString(line, "[", "]");
                                        string[] splitDate = extractDate.Split(' ');
                                        string[] splitDay = splitDate[1].Split(',');
                                        missionDate = splitDay[0] + "/" + splitDate[0] + "/" + splitDate[2];
                                    }
                                    break;
                                }
                                #endregion

                                #region Connection
                                if ((action == "has connected") || (action == "has disconnected"))
                                {
                                    string newPlayer = ParseSubString(ParseSubString(line, "M] ", " has"), "] ").ToString().Trim();
                                    if (action == "has connected")
                                    {
                                        bool addPlayer = false;
                                        if (playerStats.Count == 0)
                                            addPlayer = true;
                                        else
                                        {
                                            if (playerStats.Where(s => s.PlayerName == newPlayer).Any() == false)
                                                addPlayer = true;
                                            else
                                            {
                                                var objPlayerStat = playerStats.First(s => s.PlayerName == newPlayer);
                                                if (objPlayerStat.PlayerAction.Count > 0)
                                                {
                                                    if (objPlayerStat.FlightEnd == DateTime.Parse("01/01/0001 00:00:00"))
                                                    {
                                                        if (missionStats.MissionEndDateTime == DateTime.Parse("01/01/0001 00:00:00"))
                                                            objPlayerStat.FlightEnd = missionStats.MissionStartDateTime;
                                                        else
                                                            objPlayerStat.FlightEnd = missionStats.MissionEndDateTime;
                                                    }
                                                    PreParseSave(objPlayerStat, missionStats.MissionName);
                                                    objPlayerStat.PlayerAction.Clear();
                                                    // objPlayerStat.SaveData(missionStats.MissionName);
                                                }
                                                playerStats.RemoveAll(s => s.PlayerName == newPlayer);
                                                addPlayer = true;
                                            }
                                        }

                                        if (addPlayer)
                                        {
                                            PlayerStats newPlayerStat = new PlayerStats()
                                            {
                                                PlayerName = newPlayer
                                            };
                                            playerStats.Add(newPlayerStat);
                                        }
                                        if (!missionPlayers.Exists(s => s.Contains(newPlayer)))
                                            missionPlayers.Add(newPlayer.Trim());
                                    }


                                    if (action == "has disconnected")
                                    {


                                        if (playerStats.Where(s => s.PlayerName == newPlayer).Any() != false)
                                        {
                                            var objPlayerStat = playerStats.First(s => s.PlayerName == newPlayer);
                                            if (objPlayerStat.PlayerAction.Count > 0)
                                            {
                                                string[] lineString = line.Split(' ');
                                                string endTime = ParseSubString(lineString[0], "[") + " " + lineString[1].Substring(0, lineString[1].IndexOf(']'));
                                                objPlayerStat.FlightEnd = DateTime.Parse(missionDate + " " + endTime);
                                                //if (objPlayerStat.FlightEnd == DateTime.Parse("01/01/0001 00:00:00"))
                                                //{
                                                //    if (missionStats.MissionEndDateTime == DateTime.Parse("01/01/0001 00:00:00"))
                                                //        objPlayerStat.FlightEnd = missionStats.MissionStartDateTime;
                                                //    else
                                                //        objPlayerStat.FlightEnd = missionStats.MissionEndDateTime;
                                                //}

                                                bool addPlayerAction = true;
                                                if (objPlayerStat.PlayerAction.Where(a => a.GameAction == "landed at").Any() != false)
                                                    addPlayerAction = false;
                                                if (objPlayerStat.PlayerAction.Where(a => a.GameAction == "shot down by").Any() != false)
                                                    addPlayerAction = false;
                                                if (objPlayerStat.PlayerAction.Where(a => a.GameAction == "Crashed").Any() != false)
                                                    addPlayerAction = false;

                                                if (addPlayerAction)
                                                {
                                                    if (objPlayerStat.PlayerAction.Count > 0)
                                                    {
                                                        TimeSpan timeDiff = objPlayerStat.FlightEnd - objPlayerStat.FlightStart;
                                                        PlayerActions playerAction = new PlayerActions()
                                                        {
                                                            attackerUser = "AI",
                                                            attackerUSerObjectType = "",
                                                            GameAction = "Landed Mission End",
                                                            FlightTimeSeconds = Convert.ToDouble(timeDiff.TotalSeconds) > Convert.ToDouble(7200) ? 0 : Convert.ToInt32(timeDiff.TotalSeconds),
                                                            XCoord = 0,
                                                            YCoord = 0,
                                                            ActionTime = objPlayerStat.FlightEnd
                                                        };

                                                        objPlayerStat.PlayerAction.Add(playerAction);
                                                    }
                                                }
                                                PreParseSave(objPlayerStat, missionStats.MissionName);
                                                objPlayerStat.PlayerAction.Clear();
                                                //objPlayerStat.SaveData(missionStats.MissionName);
                                            }
                                            playerStats.RemoveAll(s => s.PlayerName == newPlayer);

                                        }
                                    }
                                    break;
                                }
                                #endregion

                                #region LoadOut
                                if (action == "loaded weapons '")
                                {
                                    string[] lineString = line.Split(' ');
                                    string[] playerPlane = lineString[2].Split(':');
                                    string player = playerPlane[0];
                                    string plane = playerPlane[1];
                                    string loadout = lineString[5];
                                    string fuel = lineString[7];
                                    var objPlayerStat = playerStats.First(s => s.PlayerName == player);
                                    if (objPlayerStat != null)
                                    {
                                        if (objPlayerStat.PlayerAction.Count > 0)
                                        {
                                            PreParseSave(objPlayerStat, missionStats.MissionName);
                                            //objPlayerStat.SaveData(missionStats.MissionName);
                                            if (objPlayerStat.FlightEnd == DateTime.Parse("01/01/0001 00:00:00"))
                                            {
                                                if (missionStats.MissionEndDateTime == DateTime.Parse("01/01/0001 00:00:00"))
                                                    objPlayerStat.FlightEnd = missionStats.MissionStartDateTime;
                                                else
                                                    objPlayerStat.FlightEnd = missionStats.MissionEndDateTime;
                                            }
                                            objPlayerStat.PlayerAction.Clear();

                                        }
                                        objPlayerStat.FlightStart = DateTime.Parse("01/01/0001 00:00:00");
                                        objPlayerStat.PlayerPlane = plane;
                                        objPlayerStat.Fuel = fuel;
                                        objPlayerStat.Loadout = loadout;
                                    }
                                    break;
                                }
                                #endregion

                                #region InFlight
                                if (action == "in flight")
                                {
                                    string[] lineString = line.Split(' ');
                                    string[] playerPlane = lineString[2].Split(':');
                                    string player = playerPlane[0];
                                    double xCoord = 0;
                                    double yCoord = 0;
                                    string startTime = ParseSubString(lineString[0], "[") + " " + lineString[1].Substring(0, lineString[1].IndexOf(']'));
                                    if (lineString.Length == 9)
                                    {
                                        xCoord = Convert.ToDouble(lineString[7]);
                                        yCoord = Convert.ToDouble(lineString[8]);
                                    }
                                    else
                                    {
                                        xCoord = Convert.ToDouble(lineString[6]);
                                        yCoord = Convert.ToDouble(lineString[7]);
                                    }

                                    var objPlayerStat = playerStats.First(s => s.PlayerName == player);
                                    if (objPlayerStat != null)
                                    {

                                        if (objPlayerStat.FlightStart != DateTime.Parse("01/01/0001 00:00:00"))
                                        {
                                            if (objPlayerStat.FlightEnd == DateTime.Parse("01/01/0001 00:00:00"))
                                            {
                                                if (missionStats.MissionEndDateTime == DateTime.Parse("01/01/0001 00:00:00"))
                                                    objPlayerStat.FlightEnd = missionStats.MissionStartDateTime;
                                                else
                                                    objPlayerStat.FlightEnd = missionStats.MissionEndDateTime;
                                            }
                                            PreParseSave(objPlayerStat, missionStats.MissionName);
                                            //objPlayerStat.SaveData(missionStats.MissionName);
                                            objPlayerStat.PlayerAction.Clear();
                                        }

                                        objPlayerStat.FlightStart = DateTime.Parse(missionDate + " " + startTime);

                                        PlayerActions playerAction = new PlayerActions()
                                        {
                                            attackerUser = "AI",
                                            attackerUSerObjectType = "",
                                            GameAction = "Take Off",
                                            FlightTimeSeconds = 0,
                                            XCoord = xCoord,
                                            YCoord = yCoord,
                                            ActionTime = objPlayerStat.FlightStart
                                        };

                                        objPlayerStat.PlayerAction.Add(playerAction);
                                        objPlayerStat.WasKilled = false;
                                    }
                                    break;

                                }
                                #endregion

                                #region MissionBegin
                                if (action == "Mission BEGIN")
                                {
                                    string[] lineString = line.Split(' ');
                                    string startTime = ParseSubString(lineString[0], "[") + " " + lineString[1].Substring(0, lineString[1].IndexOf(']'));
                                    missionStats.MissionStartDateTime = DateTime.Parse(missionDate + " " + startTime);
                                    missionStats.SaveData();
                                    break;


                                }
                                #endregion

                                #region MissionEnd
                                if (action == "Mission END")
                                {
                                    string[] lineString = line.Split(' ');
                                    string endTime = ParseSubString(lineString[0], "[") + " " + lineString[1].Substring(0, lineString[1].IndexOf(']'));
                                    missionStats.MissionEndDateTime = DateTime.Parse(missionDate + " " + endTime);
                                    break;
                                }
                                #endregion

                                #region DeathEvents
                                if (((action == "shot down by") || (action == "was killed") || (action == "damaged by") || (action == "destroyed by") || (action == "has chute destroyed by") || (action == "landed at") || (action == "crashed at")) && (line.LastIndexOf(":") >= line.IndexOf("]")))
                                {
                                    string[] lineString = line.Split(' ');
                                    //string[] playerPlane = lineString[2].Split(':');
                                    string attackerUser = "", attackerUSerObjectType = "", attackedUser = "", attackedUserObjectType = "";
                                    string gameAction = action;
                                    double xCoord = 0;
                                    double yCoord = 0;

                                    bool wasKilled = false;

                                    if (lineString[2].IndexOf(":") != -1)
                                    {
                                        string[] attackerPlayerPlane = lineString[2].Split(':');
                                        attackedUser = attackerPlayerPlane[0];
                                        attackedUserObjectType = attackerPlayerPlane[1];

                                    }
                                    else
                                    {
                                        attackedUser = lineString[2];
                                        attackedUserObjectType = lineString[2]; //ParseSubString(ParseSubString(line, "by", "at").Trim(), " ");  
                                        if (playerStats.Where(s => s.PlayerName == attackedUser).Any() == false)
                                        {

                                            attackedUser = "AI";
                                            string objectToCheck = "";
                                            if (lineString[2] != "")
                                                objectToCheck = ConvertObjectToMissionObject(lineString[2]);
                                            else
                                                objectToCheck = ConvertObjectToMissionObject(lineString[3]);

                                            if (objectToCheck.Length >= 6)
                                                if (objectToCheck.Substring(0, 6) == "Bridge")
                                                    attackedUserObjectType = "Bridge";

                                            if (attackedUserObjectType != "Bridge")
                                            {

                                                attackedUserObjectType = ExtractListItems(missionFile, objectToCheck);
                                                if (attackedUserObjectType == "")
                                                {
                                                    attackedUserObjectType = ExtractListItems(missionFile, RemoveObjectNumberFromStaticObject(objectToCheck));
                                                }
                                                if (attackedUserObjectType == "")
                                                {
                                                    if (objectToCheck == "NONAME")
                                                        attackedUserObjectType = "NONAME";
                                                    else
                                                        if ((objectToCheck == "R-10") || ((objectToCheck.IndexOf("static") == -1) && (objectToCheck.IndexOf("chief") == -1)))
                                                            attackedUserObjectType = objectToCheck;
                                                        else
                                                            attackedUserObjectType = string.Format("Unknown Object {0}", objectToCheck);
                                                }
                                            }


                                        }
                                    }


                                    if (action == "shot down by")
                                    {

                                        if (lineString.Length == 11)
                                        {
                                            xCoord = Convert.ToDouble(lineString[9]);
                                            yCoord = Convert.ToDouble(lineString[10]);
                                        }
                                        else
                                        {
                                            xCoord = Convert.ToDouble(lineString[8]);
                                            yCoord = Convert.ToDouble(lineString[9]);
                                        }

                                        if (lineString[6].IndexOf(":") != -1)
                                        {
                                            string[] attackerPlayerPlane = lineString[6].Split(':');
                                            attackerUser = attackerPlayerPlane[0];
                                            attackerUSerObjectType = attackerPlayerPlane[1];

                                        }
                                        else
                                        {
                                            attackerUser = lineString[6];
                                            if (lineString[6] == "landscape")
                                                attackerUSerObjectType = "landscape";
                                            else
                                            {
                                                if (playerStats.Where(s => s.PlayerName == attackerUser).Any() == false)
                                                {

                                                    attackerUser = "AI";
                                                    string objectToCheck = "";
                                                    if (lineString.Length == 11)
                                                        objectToCheck = ConvertObjectToMissionObject(lineString[7]);
                                                    else
                                                        objectToCheck = ConvertObjectToMissionObject(lineString[6]);
                                                    if (objectToCheck.Length >= 6)
                                                        if (objectToCheck.Substring(0, 6) == "Bridge")
                                                            attackerUSerObjectType = "Bridge";

                                                    if (attackerUSerObjectType != "Bridge")
                                                    {
                                                        attackerUSerObjectType = ExtractListItems(missionFile, objectToCheck);

                                                        if (attackerUSerObjectType == "")
                                                        {
                                                            attackerUSerObjectType = ExtractListItems(missionFile, RemoveObjectNumberFromStaticObject(objectToCheck));
                                                        }
                                                        if (attackerUSerObjectType == "")
                                                        {
                                                            if ((objectToCheck == "R-10") || ((objectToCheck.IndexOf("static") == -1) && (objectToCheck.IndexOf("chief") == -1)))
                                                                attackerUSerObjectType = objectToCheck;
                                                            else
                                                                attackerUSerObjectType = string.Format("Unknown Object SDB {0}", lineCounter);
                                                        }
                                                    }


                                                }
                                            }

                                        }

                                    }

                                    if (action == "damaged by")
                                    {
                                        xCoord = Convert.ToDouble(lineString[7]);
                                        yCoord = Convert.ToDouble(lineString[8]);
                                        if (lineString[5].IndexOf(":") != -1)
                                        {
                                            string[] attackerPlayerPlane = lineString[5].Split(':');
                                            attackerUser = attackerPlayerPlane[0];
                                            attackerUSerObjectType = attackerPlayerPlane[1];
                                        }
                                        else
                                        {
                                            //string[] attackerPlayerPlane = lineString[5].Split('M]');
                                            attackerUser = lineString[5];
                                            if (lineString[5] == "landscape")
                                                attackerUSerObjectType = "landscape";
                                            else
                                            {
                                                if (playerStats.Where(s => s.PlayerName == attackerUser).Any() == false)
                                                {

                                                    attackerUser = "AI";
                                                    string objectToCheck = ConvertObjectToMissionObject(lineString[5]);
                                                    attackedUserObjectType = ExtractListItems(missionFile, objectToCheck);
                                                    attackerUSerObjectType = ExtractListItems(missionFile, objectToCheck);
                                                    if (attackerUSerObjectType == "")
                                                    {
                                                        attackerUSerObjectType = ExtractListItems(missionFile, RemoveObjectNumberFromStaticObject(objectToCheck));
                                                    }
                                                    if (attackerUSerObjectType == "")
                                                    {
                                                        if (objectToCheck == "NONAME")
                                                            attackerUSerObjectType = "NONAME";
                                                        else
                                                        {
                                                            if ((objectToCheck == "R-10") || ((objectToCheck.IndexOf("static") == -1) && (objectToCheck.IndexOf("chief") == -1)))
                                                                attackerUSerObjectType = objectToCheck;
                                                            else
                                                                attackerUSerObjectType = string.Format("Unknown Damaged {0}", lineCounter);
                                                        }
                                                    }


                                                }
                                            }
                                            //attackerUSerObjectType = attackerPlayerPlane[1];
                                        }
                                    }

                                    if (action == "destroyed by")
                                    {
                                        int checkUserArrayPos = 0;
                                        int checkObjectArrayPos = 0;
                                        if (lineString.Length == 10)
                                        {
                                            xCoord = Convert.ToDouble(lineString[8]);
                                            yCoord = Convert.ToDouble(lineString[9]);
                                            checkUserArrayPos = 6;
                                            checkObjectArrayPos = 3;
                                        }
                                        else
                                        {
                                            xCoord = Convert.ToDouble(lineString[7]);
                                            yCoord = Convert.ToDouble(lineString[8]);
                                            checkUserArrayPos = 5;
                                            checkObjectArrayPos = 2;
                                        }
                                        if (lineString[checkUserArrayPos].IndexOf(":") != -1)
                                        {
                                            string[] attackerPlayerPlane = lineString[checkUserArrayPos].Split(':');
                                            attackerUser = attackerPlayerPlane[0];
                                            attackerUSerObjectType = attackerPlayerPlane[1];

                                            if (playerStats.Where(s => s.PlayerName == attackedUser).Any() == false)
                                            {

                                                attackedUser = "AI";
                                                if (lineString[checkObjectArrayPos].IndexOf("Bridge") != -1)
                                                {
                                                    attackedUserObjectType = "Bridge";
                                                }
                                                else
                                                {
                                                    attackedUserObjectType = ExtractListItems(missionFile, lineString[checkObjectArrayPos]);
                                                    if (attackedUserObjectType == "")
                                                    {
                                                        attackedUserObjectType = ExtractListItems(missionFile, RemoveObjectNumberFromStaticObject(lineString[checkObjectArrayPos]));
                                                    }



                                                    if (attackedUserObjectType == "")
                                                        attackedUserObjectType = string.Format("Unknown Destroyed {0}", lineString[checkObjectArrayPos]);
                                                    else
                                                    {
                                                        if (FirstPositionIsNumeric(attackedUserObjectType))
                                                            attackedUserObjectType = attackedUserObjectType.Substring(attackedUserObjectType.IndexOf("-") + 1);
                                                    }
                                                }
                                                currentAction = "destroyed";
                                            }

                                        }
                                        else
                                        {
                                            attackerUser = lineString[5];
                                            attackerUSerObjectType = lineString[5];
                                        }


                                    }

                                    if (action == "damaged on the ground")
                                    {
                                        xCoord = Convert.ToDouble(lineString[8]);
                                        yCoord = Convert.ToDouble(lineString[9]);
                                    }

                                    if (action == "has chute destroyed by")
                                    {
                                        xCoord = Convert.ToDouble(lineString[9]);
                                        yCoord = Convert.ToDouble(lineString[10]);
                                    }

                                    if (action == "was killed")
                                    {
                                        if (lineString.Length == 13)
                                        {
                                            xCoord = Convert.ToDouble(lineString[11]);
                                            yCoord = Convert.ToDouble(lineString[12]);
                                        }
                                        else if (lineString.Length == 10)
                                        {
                                            xCoord = Convert.ToDouble(lineString[8]);
                                            yCoord = Convert.ToDouble(lineString[9]);
                                        }
                                        else
                                        {
                                            xCoord = Convert.ToDouble(lineString[6]);
                                            yCoord = Convert.ToDouble(lineString[7]);
                                        }
                                        wasKilled = true;
                                    }

                                    if (action == "landed at")
                                    {
                                        xCoord = Convert.ToDouble(lineString[5]);
                                        yCoord = Convert.ToDouble(lineString[6]);
                                    }

                                    if (action == "crashed at")
                                    {
                                        xCoord = Convert.ToDouble(lineString[5]);
                                        yCoord = Convert.ToDouble(lineString[6]);
                                    }

                                    if (attackerUSerObjectType == "landscape")
                                    {
                                        attackerUser = "Crashed";
                                        gameAction = "Crashed";
                                        attackerUSerObjectType = "into the ground";

                                    }

                                    if (playerStats.Where(s => s.PlayerName == attackerUser).Any() == false)
                                    {
                                        attackerUser = "AI";
                                    }

                                    string endTime = ParseSubString(lineString[0], "[") + " " + lineString[1].Substring(0, lineString[1].IndexOf(']'));

                                    if (playerStats.Where(s => s.PlayerName == attackedUser).Any() != false)
                                    {
                                        if (AddPlayerEvent(attackedUserObjectType))
                                        {
                                            var objPlayerStat = playerStats.First(s => s.PlayerName == attackedUser);
                                            if (objPlayerStat != null)
                                            {
                                                bool addPlayerAction = true;



                                                if (addPlayerAction)
                                                {
                                                    if (objPlayerStat.PlayerAction.Count > 0)
                                                    {
                                                        objPlayerStat.FlightEnd = DateTime.Parse(missionDate + " " + endTime);

                                                        if (objPlayerStat.FlightStart == DateTime.Parse("01/01/0001 00:00:00"))
                                                        {
                                                            string startTime = ParseSubString(lineString[0], "[") + " " + lineString[1].Substring(0, lineString[1].IndexOf(']'));
                                                            objPlayerStat.FlightStart = DateTime.Parse(missionDate + " " + startTime);
                                                        }

                                                        TimeSpan timeDiff = objPlayerStat.FlightEnd - objPlayerStat.FlightStart;

                                                        PlayerActions playerAction = new PlayerActions()
                                                        {
                                                            attackerUser = attackerUser,
                                                            attackerUSerObjectType = attackerUSerObjectType,
                                                            GameAction = gameAction,
                                                            FlightTimeSeconds = Convert.ToDouble(timeDiff.TotalSeconds) > Convert.ToDouble(7200) ? 0 : Convert.ToInt32(timeDiff.TotalSeconds),
                                                            XCoord = xCoord,
                                                            YCoord = yCoord,
                                                            ActionTime = objPlayerStat.FlightEnd
                                                        };

                                                        objPlayerStat.PlayerAction.Add(playerAction);

                                                        //check for shot down by and add relevant kill to person who did the shooting
                                                        if ((gameAction == "shot down by") && (attackerUser != "AI"))
                                                        {
                                                            if (playerStats.Where(s => s.PlayerName == attackerUser).Any() != false)
                                                            {
                                                                var objPlayerStatAtt = playerStats.First(s => s.PlayerName == attackerUser);
                                                                if (objPlayerStatAtt != null)
                                                                {
                                                                    if (objPlayerStatAtt.PlayerAction.Count > 0)
                                                                    {
                                                                        objPlayerStatAtt.FlightEnd = DateTime.Parse(missionDate + " " + endTime);

                                                                        if (objPlayerStatAtt.FlightStart == DateTime.Parse("01/01/0001 00:00:00"))
                                                                        {
                                                                            string startTime = ParseSubString(lineString[0], "[") + " " + lineString[1].Substring(0, lineString[1].IndexOf(']'));
                                                                            objPlayerStatAtt.FlightStart = DateTime.Parse(missionDate + " " + startTime);
                                                                        }

                                                                        TimeSpan timeDiffAtt = objPlayerStatAtt.FlightEnd - objPlayerStatAtt.FlightStart;

                                                                        PlayerActions playerActionAtt = new PlayerActions()
                                                                        {
                                                                            attackerUser = attackedUser,
                                                                            attackerUSerObjectType = attackedUserObjectType,
                                                                            GameAction = "shot down",
                                                                            FlightTimeSeconds = Convert.ToDouble(timeDiffAtt.TotalSeconds) > Convert.ToDouble(7200) ? 0 : Convert.ToInt32(timeDiffAtt.TotalSeconds),
                                                                            XCoord = xCoord,
                                                                            YCoord = yCoord,
                                                                            ActionTime = objPlayerStatAtt.FlightEnd
                                                                        };

                                                                        objPlayerStatAtt.PlayerAction.Add(playerActionAtt);
                                                                    }
                                                                }
                                                            }
                                                        }
                                                    }
                                                    if (wasKilled)
                                                        objPlayerStat.WasKilled = wasKilled;
                                                }

                                            }
                                        }
                                    }
                                    else if (playerStats.Where(s => s.PlayerName == attackerUser).Any() != false)
                                    {
                                        var objPlayerStat = playerStats.First(s => s.PlayerName == attackerUser);
                                        if (objPlayerStat != null)
                                        {
                                            if (objPlayerStat.PlayerAction.Count > 0)
                                            {
                                                if (currentAction == "")
                                                    currentAction = "shot down";
                                                objPlayerStat.FlightEnd = DateTime.Parse(missionDate + " " + endTime);
                                                if (objPlayerStat.FlightStart == DateTime.Parse("01/01/0001 00:00:00"))
                                                {
                                                    string startTime = ParseSubString(lineString[0], "[") + " " + lineString[1].Substring(0, lineString[1].IndexOf(']'));
                                                    objPlayerStat.FlightStart = DateTime.Parse(missionDate + " " + startTime);
                                                }
                                                TimeSpan timeDiff = objPlayerStat.FlightEnd - objPlayerStat.FlightStart;
                                                PlayerActions playerAction = new PlayerActions()
                                                {
                                                    attackerUser = attackedUser,
                                                    attackerUSerObjectType = attackedUserObjectType,
                                                    GameAction = currentAction,
                                                    FlightTimeSeconds = Convert.ToDouble(timeDiff.TotalSeconds) > Convert.ToDouble(7200) ? 0 : Convert.ToInt32(timeDiff.TotalSeconds),
                                                    XCoord = xCoord,
                                                    YCoord = yCoord,
                                                    ActionTime = objPlayerStat.FlightEnd
                                                };

                                                objPlayerStat.PlayerAction.Add(playerAction);
                                                if (wasKilled)
                                                    objPlayerStat.WasKilled = wasKilled;
                                            }
                                        }
                                    }
                                    //}


                                    break; ;
                                }
                                #endregion
                            }

                        }
                    }
                }
            }
            #endregion

            //check if we got a MissionEndDate
            if (missionStats.MissionEndDateTime == DateTime.Parse("01/01/0001 00:00:00"))
            {
                string[] lineString = lastLine.Split(' ');
                string endTime = ParseSubString(lineString[0], "[") + " " + lineString[1].Substring(0, lineString[1].IndexOf(']'));
                missionStats.MissionEndDateTime = DateTime.Parse(missionDate + " " + endTime);
            }

            //Save all the playerStats that have not yet been saved.
            foreach (PlayerStats playerStat in playerStats)
            {

                if (playerStat.FlightStart == DateTime.Parse("01/01/0001 00:00:00"))
                    playerStat.FlightStart = missionStats.MissionEndDateTime;
                //if the player is still flying at mission end then end the flight at the mission end time
                //and added a landed action
                if (playerStat.FlightEnd == DateTime.Parse("01/01/0001 00:00:00"))
                    playerStat.FlightEnd = missionStats.MissionEndDateTime;

                bool addPlayerAction = true;

                if (playerStat.PlayerAction.Where(a => a.GameAction == "landed at").Any() != false)
                    addPlayerAction = false;
                if (playerStat.PlayerAction.Where(a => a.GameAction == "shot down by").Any() != false)
                    addPlayerAction = false;
                if (playerStat.PlayerAction.Where(a => a.GameAction == "Crashed").Any() != false)
                    addPlayerAction = false;

                if (addPlayerAction)
                {
                    if (playerStat.PlayerAction.Count > 0)
                    {
                        TimeSpan timeDiff = playerStat.FlightEnd - playerStat.FlightStart;
                        PlayerActions playerAction = new PlayerActions()
                        {
                            attackerUser = "AI",
                            attackerUSerObjectType = "",
                            GameAction = "Landed Mission End",
                            FlightTimeSeconds = Convert.ToDouble(timeDiff.TotalSeconds)<0 ?0 :( Convert.ToDouble(timeDiff.TotalSeconds) > Convert.ToDouble(7200) ? 0 : Convert.ToInt32(timeDiff.TotalSeconds)),
                            XCoord = 0,
                            YCoord = 0,
                            ActionTime = playerStat.FlightEnd
                        };

                        playerStat.PlayerAction.Add(playerAction);
                    }
                }

                PreParseSave(playerStat, missionStats.MissionName);


            }
        }
        /// <summary>
        /// Don't add multi crew object events apart from crew member 0
        /// </summary>
        /// <param name="objectToCheck"></param>
        /// <returns></returns>
        static bool AddPlayerEvent(string objectToCheck)
        {
            if (objectToCheck == "")
                return true;
            else
            {
                if (objectToCheck.Substring(objectToCheck.Length - 1, 1) != ")")
                    return true;
                else
                {
                    if (objectToCheck.Substring(objectToCheck.Length - 2, 2) == "0)")
                        return true;
                    else
                        return false;
                }
            }



        }


        /// <summary>
        /// Only procoess those lines that do not exclusively contain static objects
        /// </summary>
        /// <param name="line">String to search for static objects.</param>
        /// <returns></returns>
        static bool NonAIActions(string line)
        {
            if ((CountStringMatchs(line, "Static") + CountStringMatchs(line, "Chief")) > 1)
                return false;

            return true;
        }
        /// <summary>
        /// Provides a count of the instances of the pattern in the string.
        /// </summary>
        /// <param name="line">String to search.</param>
        /// <param name="pattern">Pattern to match.</param>
        /// <returns></returns>
        static int CountStringMatchs(string line, string pattern)
        {

            int patternCount = 0;
            int stringPos = 0;
            while ((stringPos = line.IndexOf(pattern, stringPos)) != -1)
            {
                stringPos += pattern.Length;
                patternCount++;
            }
            return patternCount;
        }

        /// <summary>
        /// Update the missionStats object with the mission details as read from the Mission File.
        /// </summary>
        /// <param name="missionFile">List of Mission File items.</param>
        /// <param name="missionStats">MissionStats object to set.</param>
        static void ExtractMissionAttributes(List<string> missionFile, MissionStats missionStats)
        {

            missionStats.MissionMapName = ExtractListItems(missionFile, "MAP");
            missionStats.MissionDateTime = DateTime.Parse((ExtractListItems(missionFile, "Day") + "/" + ExtractListItems(missionFile, "Month") + "/" + ExtractListItems(missionFile, "Year") + " " + ExtractListItems(missionFile, "TIME")), CultureInfo.GetCultureInfo("en-GB"));
            missionStats.CloudType = Convert.ToInt32(ExtractListItems(missionFile, "CloudType"));
            missionStats.CloudHeight = Convert.ToInt32(ExtractListItems(missionFile, "CloudHeight"));
            missionStats.WindDirection = Convert.ToDecimal(ExtractListItems(missionFile, "WindDirection"));
            missionStats.WindSpeed = Convert.ToDecimal(ExtractListItems(missionFile, "WindSpeed"));
            missionStats.Gust = Convert.ToInt32(ExtractListItems(missionFile, "Gust"));
            missionStats.Turbulence = Convert.ToInt32(ExtractListItems(missionFile, "Turbulence"));
            missionStats.GameType = 0;

        }

        /// <summary>
        /// Removes the internal IL2 object number from the static object.
        /// </summary>
        /// <param name="objectToCheck"><String to check for an internal IL2 object number./param>
        /// <returns></returns>
        static string RemoveObjectNumberFromStaticObject(string objectToCheck)
        {
            if ((objectToCheck.IndexOf("Static") != -1) || (objectToCheck.IndexOf("Chief") != -1))
            {
                if (objectToCheck.IndexOf("Chief") != -1)
                {
                    return objectToCheck.Substring(0, objectToCheck.IndexOf("Chief") + 5);
                }
                else if (objectToCheck.IndexOf("Static") != -1)
                {

                    return objectToCheck.Substring(0, objectToCheck.IndexOf("Static") + 6);
                }
                else
                    return objectToCheck;

            }
            else
                return objectToCheck;

        }

        static bool FirstPositionIsNumeric(string objectToCheck)
        {
            if ("1234567780".IndexOf(objectToCheck.Substring(0, 1)) != -1)
                return true;
            else
                return false;
        }


        static string ExtractListItems(List<string> objectList, string objectToCheck)
        {
            if (objectList.Exists(s => s.Contains(objectToCheck)))
            {
                var results = objectList.Find(s => s.Contains(objectToCheck));

                if (objectToCheck == "MAP")
                {
                    return ParseSubString(results, " ", "/");
                    //results.Substring(results.IndexOf(" ") + 1, results.IndexOf("/")-1 - results.IndexOf(" "));
                }
                else if ((objectToCheck == "Day") || (objectToCheck == "Month") || (objectToCheck == "Year"))
                {
                    string[] myRes = results.Split(' ');
                    return myRes[1];//.Substring                     
                }
                else if (objectToCheck == "TIME")
                {
                    return ParseSubString(results, " ", ".") + ":" + ParseSubString(results, ".");
                    //return results.Substring(results.IndexOf(" ") + 1, results.IndexOf(".") - 1 - results.IndexOf(" ")) + ":" + results.Substring(results.IndexOf(".") + 1, results.Length - 1 - results.IndexOf("."));
                }
                else if ((objectToCheck == "CloudType") || (objectToCheck == "CloudHeight") || (objectToCheck == "Gust") || (objectToCheck == "Turbulence"))
                {
                    if (ParseSubString(results, " ").IndexOf(".") > 0)
                    {
                        return ParseSubString(results, " ").Substring(0, ParseSubString(results, " ").IndexOf("."));
                    }
                    else
                        return ParseSubString(results, " ");
                    //string[] myRes = results.Substring(results.IndexOf("$") + 1).Split(' ');
                    //return "";
                }
                else if ((objectToCheck == "WindDirection") || (objectToCheck == "WindSpeed"))
                {
                    return ParseSubString(results, " ", ".") + "." + ParseSubString(results, ".");
                }
                else
                {
                    if (results.IndexOf("GATTACK") != -1)
                    {
                        var nonGATTACKResults = objectList.FindAll(s => s.Contains(objectToCheck));
                        foreach (string curResult in nonGATTACKResults)
                        {
                            if ((curResult.IndexOf("GATTACK") == -1) && (curResult.IndexOf("[") == -1))
                            {
                                string[] splitString = curResult.Split(' ');
                                if (splitString[0] == objectToCheck)
                                {
                                    if (curResult.IndexOf("$") != -1)
                                    {
                                        string[] objectDetails = curResult.Substring(curResult.IndexOf("$") + 1).Split(' ');
                                        return objectDetails[0];
                                    }
                                    else if (curResult.IndexOf(".") != -1)
                                    {
                                        string[] objectDetails = curResult.Substring(curResult.IndexOf(".") + 1).Split(' ');
                                        return objectDetails[0];
                                    }
                                    else
                                    {
                                        if (objectToCheck == curResult)
                                            return objectToCheck;
                                        else
                                            return "";
                                    }
                                }

                            }

                        }

                        return "";
                    }
                    else
                    {
                        var nonGATTACKResults = objectList.FindAll(s => s.Contains(objectToCheck));
                        foreach (string curResult in nonGATTACKResults)
                        {
                            if ((curResult.IndexOf("GATTACK") == -1) && (curResult.IndexOf("[") == -1))
                            {
                                if (curResult.IndexOf("air.") != -1)
                                {
                                    string[] splitString = curResult.Split('.');
                                    if (splitString[1] == objectToCheck)
                                    {
                                        return objectToCheck;
                                    }
                                }
                                else
                                {
                                    string[] splitString = curResult.Split(' ');
                                    if (splitString[0] == objectToCheck)
                                    {
                                        if (curResult.IndexOf("$") != -1)
                                        {
                                            string[] objectDetails = curResult.Substring(curResult.IndexOf("$") + 1).Split(' ');
                                            return objectDetails[0];
                                        }
                                        else if (curResult.IndexOf(".") != -1)
                                        {
                                            string[] objectDetails = curResult.Substring(curResult.IndexOf(".") + 1).Split(' ');
                                            return objectDetails[0];
                                        }
                                        else
                                        {
                                            if (objectToCheck == curResult)

                                                return objectToCheck;
                                            else
                                                return "";
                                        }
                                    }
                                }

                            }

                        }
                        return "";
                    }



                }
            }
            else
            {
                return "";

            }





        }

        static string ParseSubString(string results, string firstIndex, string secondIndex)
        {
            return results.Substring(results.IndexOf(firstIndex) + 1, results.IndexOf(secondIndex) - 1 - results.IndexOf(firstIndex));
        }

        static string ParseSubString(string results, string firstIndex)
        {
            return results.Substring(results.IndexOf(firstIndex) + 1, results.Length - 1 - results.IndexOf(firstIndex));
        }

        static string ConvertObjectToMissionObject(string objectToConvert)
        {
            if (objectToConvert.IndexOf("(") > -1)
                objectToConvert = objectToConvert.Substring(0, objectToConvert.IndexOf("("));
            if (objectToConvert == "Ju-52/3mg4e")
                return "JU_52_3MG4E";
            if (objectToConvert == "Li-2")
                return "LI_2";
            if (objectToConvert == "Fi-156")
                return "FI_156";
            else
                return objectToConvert;
        }

        static void PreParseSave(PlayerStats playerStat, string fileToSave)
        {

            bool playerShotDownBy = false;
            bool playerCrashed = false;
            bool playerLanded = false;
            int endArrayPos = playerStat.PlayerAction.Count - 1;
            for (int currPos = playerStat.PlayerAction.Count - 1; currPos >= 0; currPos--)
            {
                var currentAction = playerStat.PlayerAction[currPos];

                if (currentAction.GameAction == "shot down by")
                {
                    if (playerShotDownBy)
                    {
                        playerStat.PlayerAction.RemoveAt(currPos);

                    }
                    if (currPos == endArrayPos)
                        playerShotDownBy = true;
                }

                if ((currentAction.GameAction == "crashed at") || (currentAction.GameAction == "Crashed"))
                {
                    if (playerCrashed)
                    {
                        playerStat.PlayerAction.RemoveAt(currPos);

                    }
                    if (currPos == endArrayPos)
                        playerCrashed = true;
                }

                if ((currentAction.GameAction == "landed at") || (currentAction.GameAction == "Landed Mission End"))
                {
                    if (playerLanded)
                    {
                        playerStat.PlayerAction.RemoveAt(currPos);

                    }

                    if (currPos == endArrayPos)
                        playerLanded = true;

                    if ((currPos - 1) >= 0)
                    {
                        if ((playerStat.PlayerAction[currPos - 1].GameAction == "Crashed") || (playerStat.PlayerAction[currPos - 1].GameAction == "crashed at"))
                        {
                            if (!playerShotDownBy)
                            {
                                playerStat.PlayerAction.RemoveAt(currPos);
                                playerLanded = false;
                                endArrayPos = currPos - 1;

                            }
                        }
                    }
                }

                if ((currentAction.GameAction == "was killed") && ((playerShotDownBy) || (playerCrashed)))
                    playerStat.PlayerAction.RemoveAt(currPos);


                //if ((currentAction.GameAction == "was killed by") && (playerShotDownBy))
                //  playerStat.PlayerAction.RemoveAt(currPos);


                if ((currentAction.GameAction == "damaged by") && (playerShotDownBy))
                    playerStat.PlayerAction.RemoveAt(currPos);


                if ((playerCrashed) && ((currentAction.GameAction == "landed at") || (currentAction.GameAction == "Landed Mission End")))
                    playerStat.PlayerAction.RemoveAt(currPos);

                if ((playerLanded) && (currentAction.GameAction == "damaged by"))
                    playerStat.PlayerAction.RemoveAt(currPos);

                if ((playerShotDownBy) && (currentAction.GameAction == "Crashed"))
                    playerStat.PlayerAction.RemoveAt(currPos);

                if ((playerShotDownBy) && ((currentAction.GameAction == "landed at") || (currentAction.GameAction == "Landed Mission End")))
                    playerStat.PlayerAction.RemoveAt(currPos);

                if ((currentAction.GameAction == "damaged by") && (playerCrashed))
                    playerStat.PlayerAction.RemoveAt(currPos);
            }

            playerStat.SaveData(fileToSave);
        }

    }
}

